/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package comp.racer.rn;

import comp.racer.ip.Ranking;
import comp.racer.ip.TextoPersistencia;
import comp.racer.so.Servidor;
import comp.racer.common.rn.Jogador;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

/**
 *
 * @author david
 */
public class Partida {
    private TextoPersistencia texto;
    private Servidor servidor;
    private Ranking ranking;
    private Calendar inicioPartida;
    private boolean partidaEncerrada;
    private Map<Jogador, Integer> jogadorPosicaoRankingMap;

    public Partida(TextoPersistencia texto) {
        setTexto(texto);
        setRanking(new Ranking());
        setInicioPartida(Calendar.getInstance());
        setServidor(Servidor.getInstancia());
        setPartidaEncerrada(false);
    }

    public Jogador atualizaProgressoJogadores(Jogador jogador, int numCaracteresCorretos) {

        System.out.println("\nPartida: atualizaProgressoJogadores : " + jogador.getLogin());
        Jogador jogadorAtualizado = getLoginJogadorMap().get(jogador.getLogin());

        int novoProgresso = jogadorAtualizado.getProgresso() + numCaracteresCorretos;

        Calendar atualCalendar = Calendar.getInstance();
        float segundosDecorridos = (atualCalendar.getTimeInMillis() - getInicioPartida().getTimeInMillis()) / 1000;
        float novoCPM = (novoProgresso) / ((segundosDecorridos) / 60);

        jogadorAtualizado.setCpm(novoCPM);
        jogadorAtualizado.setProgresso(novoProgresso);

        if (jogadorAtualizado.getProgresso() >= getTexto().getNumeroCaracteres()) {
            jogadorAtualizado.setEstado(Jogador.FINALIZADO);
        }

        setPartidaEncerrada(true);

        Collection<Jogador> listaJogadores = getLoginJogadorMap().values();

        for (Jogador jogadorAtual : listaJogadores) {
            if (jogadorAtual.getEstado() != Jogador.FINALIZADO) {
                setPartidaEncerrada(false);
            }
        }

        if (isPartidaEncerrada()) {
            encerraPartida();
        }

        return jogadorAtualizado;


    }

    private void encerraPartida() {

        System.out.println("\nPartida: encerraPartida");

        List<Jogador> classificacaoList = getJogadorList();
        Collections.sort(classificacaoList);

        Map<Jogador, Integer> jogadorPosicaoRankingMap = getRanking().atualizaRanking( classificacaoList );

        setJogadorPosicaoRankingMap( jogadorPosicaoRankingMap );
        setPartidaEncerrada(true);

    }

    // getters s setters
    public boolean isPartidaEncerrada() {
        return partidaEncerrada;
    }

    public void setPartidaEncerrada(boolean partidaEncerrada) {
        this.partidaEncerrada = partidaEncerrada;
    }

    public Map<String, Jogador> getLoginJogadorMap() {
        return Servidor.getInstancia().getLoginJogadorMap();
    }

    public void setLoginJogadorMap(Map<String, Jogador> loginJogadorMap) {
        Servidor.getInstancia().setLoginJogadorMap(loginJogadorMap);
    }

    public List<Jogador> getJogadorList() {
        return new Vector(  getLoginJogadorMap().values() );
    }

    public Map<Jogador, Integer> getJogadorPosicaoRankingMap() {
        return jogadorPosicaoRankingMap;
    }

    public void setJogadorPosicaoRankingMap(Map<Jogador, Integer> jogadorPosicaoRankingMap) {
        this.jogadorPosicaoRankingMap = jogadorPosicaoRankingMap;
    }

    public Calendar getInicioPartida() {
        return inicioPartida;
    }

    public void setInicioPartida(Calendar inicioPartida) {
        this.inicioPartida = inicioPartida;
    }

    public Ranking getRanking() {
        return ranking;
    }

    public void setRanking(Ranking ranking) {
        this.ranking = ranking;
    }

    public Servidor getServidor() {
        return servidor;
    }

    public void setServidor(Servidor servidor) {
        this.servidor = servidor;
    }

    public TextoPersistencia getTexto() {
        return texto;
    }

    public void setTexto(TextoPersistencia texto) {
        this.texto = texto;
    }


}
